home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Source Code
/
Pascal
/
Snippets
/
Billiards
/
components.p
< prev
next >
Wrap
Text File
|
1996-09-29
|
3KB
|
167 lines
{ components for billiard simulation }
{ written by Tim Budd, Oregon State University }
{ April 1990 }
unit billiardComponents;
interface
uses
graphicUniverse;
type
wall = object(GraphicalObject)
convertFactor: real;
procedure setBounds (left, top, right, bottom: integer; cf: real);
procedure draw; override;
procedure hitBy (anObject: GraphicalObject); override;
end;
hole = object(GraphicalObject)
procedure setCenter (x, y: integer);
procedure draw; override;
procedure hitBy (anObject: GraphicalObject); override;
end;
ball = object(hole)
direction: real;
energy: real;
procedure draw; override;
procedure update; override;
procedure hitBy (anObject: GraphicalObject); override;
function x: real;
function y: real;
end;
var
theUniverse: ObjectUniverse;
cueBall: ball;
saveRack: integer;
function hitAngle (dx, dy: real): real;
implementation
function hitAngle (dx, dy: real): real;
const
PI = 3.14159;
var
na: real;
begin
if (abs(dx) < 0.05) then
na := PI / 2
else
na := arctan(abs(dy / dx));
if (dx < 0) then
na := PI - na;
if (dy < 0) then
na := -na;
hitAngle := na;
end;
procedure wall.setBounds (left, top, right, bottom: integer; cf: real);
begin
convertFactor := cf;
SetRect(region, left, top, right, bottom);
end;
procedure wall.draw;
begin
PaintRect(region);
end;
procedure wall.hitBy (anObject: GraphicalObject);
var
theBall: ball;
begin
theBall := ball(anObject);
theBall.direction := convertFactor - theBall.direction;
theUniverse.continueSimulation;
draw;
end;
procedure hole.setCenter (x, y: integer);
begin
SetRect(region, x - 5, y - 5, x + 5, y + 5);
end;
procedure hole.draw;
begin
PaintOval(region);
end;
procedure hole.hitBy (anObject: GraphicalObject);
var
theBall: ball;
begin
theBall := ball(anObject);
if (theBall = cueBall) then
theBall.setCenter(50, 100)
else
begin
saveRack := saveRack + 1;
theBall.setCenter(10 + saveRack * 15, 250);
end;
theBall.energy := 0.0;
anObject.draw;
end;
function ball.x: real;
begin
x := (region.left + region.right) / 2;
end;
function ball.y: real;
begin
y := (region.top + region.bottom) / 2;
end;
procedure ball.draw;
begin
if (self = cueBall) then
FrameOval(region)
else
PaintOval(region);
end;
procedure ball.update;
var
hit: GraphicalObject;
dx, dy: integer;
i, xdir, ydir, ymove: integer;
begin
if (energy > 0.5) then
begin
erase;
energy := energy - 0.05;
if energy > 0.5 then
theUniverse.continueSimulation;
dx := trunc(5.0 * cos(direction));
dy := trunc(5.0 * sin(direction));
offsetRect(region, dx, dy);
hit := theUniverse.hitObject(self);
if hit <> nil then
begin
hit.hitBy(self);
theUniverse.draw;
end
else
draw;
end;
end;
procedure ball.hitBy (anObject: GraphicalObject);
var
aBall: ball;
da: real;
begin
aBall := ball(anObject);
energy := aBall.energy / 2;
aBall.energy := energy;
direction := hitAngle(self.x - aBall.x, self.y - aBall.y);
da := aBall.direction - direction;
aBall.direction := aBall.direction + da;
theUniverse.continueSimulation;
end;
end.